package com.ape.mapsa.common;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.el.MethodExpression;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.MethodExpressionActionListener;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.util.JRLoader;

import org.apache.log4j.Logger;
import org.primefaces.component.menuitem.MenuItem;
import org.primefaces.component.submenu.Submenu;
import org.primefaces.context.RequestContext;
import org.primefaces.event.CellEditEvent;
import org.primefaces.event.RowEditEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.MenuModel;

import com.ape.mapsa.common.constants.ProdAction;
import com.ape.mapsa.common.constants.TipoMaterial;
import com.ape.mapsa.model.UserRole;
import com.ape.mapsa.produccion.model.ConfPerformedWork;
import com.ape.mapsa.produccion.model.ConfProdScrap;
import com.ape.mapsa.produccion.model.EstadoProduccion;
import com.ape.mapsa.produccion.model.ExtPerformedWork;
import com.ape.mapsa.produccion.model.ExtProdScrap;
import com.ape.mapsa.produccion.model.Formula;
import com.ape.mapsa.produccion.model.ImpPerformedWork;
import com.ape.mapsa.produccion.model.ImpProdScrap;
import com.ape.mapsa.produccion.model.OpComment;
import com.ape.mapsa.produccion.model.OrdenProduccion;
import com.ape.mapsa.produccion.model.ProdOperator;
import com.ape.mapsa.produccion.service.IProduccionService;

@ManagedBean(name = "ordenProdMB")
@ViewScoped
public class OrdenProdBean extends BeanCRUD implements Serializable {

	private static final long serialVersionUID = -5744337830986575883L;

	@ManagedProperty(value = "#{produccionService}")
	private IProduccionService produccionService;

	@ManagedProperty(value = "#{userMB}")
	private UserBean userBean;

	@ManagedProperty(value = "#{homeMenuMB}")
	private UserHomeMenuBean homeBean;

	@ManagedProperty(value = "#{formulasMB}")
	private FormulasBean formulaBean;

	private ProdAction action;
	private ProdAction[] actions;

	private boolean showComment;
	private String comment;

	private boolean renderPerformedWork;

	private static final Logger log = Logger.getLogger(OrdenProdBean.class);

	private String ordenProdID;
	private List<OrdenProduccion> filteredOrdenProds;
	private List<OrdenProduccion> ordenesProd;
	private OrdenProduccion selectedOp;
	private boolean renderOpDetails = false;
	private boolean renderOpComments = false;

	private TipoMaterial tipoMaterial;

	private String state;

	private EstadoProduccion estadoFiltro;

	private List<ExtPerformedWork> extPerformedWorks;
	private List<ExtProdScrap> extScrap;

	private List<ImpPerformedWork> impPerformedWorks;
	private List<ImpProdScrap> impScrap;

	private List<ConfPerformedWork> confPerformedWorks;
	private List<ConfProdScrap> confScrap;

	private Long selectedId;

	private Long temporalId = 0L;
	private Long impTemporalId = 0L;
	private Long confTemporalId = 0L;

	private Long scrapTemporalId = 0L;
	private Long impScrapTemporalId = 0L;
	private Long confScrapTemporalId = 0L;

	private List<ProdOperator> operatorsAutocomp;
	private ProdOperator selectedOperator = new ProdOperator();
	private String selectedOperatorStr;

	private ExtPerformedWork extEditingRow;

	private boolean operatorSelected;

	private Date currentDate = new Date();

	public String getOrdenProdID() {
		return ordenProdID;
	}

	public void onExtCellEdit(CellEditEvent event) {
		if (operatorSelected) {
			Object oldValue = event.getOldValue();
			Object newValue = event.getNewValue();
			log.debug(" Editado " + extPerformedWorks.get(event.getRowIndex()).getBobinaN());
			extPerformedWorks.get(event.getRowIndex()).setProdOperator(selectedOperator);
			if (newValue != null && !newValue.equals(oldValue)) {
				FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Operario seleccionado ", "" + newValue);
				FacesContext.getCurrentInstance().addMessage(null, msg);
			}
			operatorSelected = false;
			selectedOperator = null;
			selectedOperatorStr = "";
		}
	}

	public void onImpCellEdit(CellEditEvent event) {
		if (operatorSelected) {
			Object oldValue = event.getOldValue();
			Object newValue = event.getNewValue();
			log.debug(" Editado " + extPerformedWorks.get(event.getRowIndex()).getBobinaN());
			impPerformedWorks.get(event.getRowIndex()).setProdOperator(selectedOperator);
			if (newValue != null && !newValue.equals(oldValue)) {
				FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Operario seleccionado ", "" + newValue);
				FacesContext.getCurrentInstance().addMessage(null, msg);
			}
			operatorSelected = false;
			selectedOperator = null;
			selectedOperatorStr = "";
		}
	}

	public void onConfCellEdit(CellEditEvent event) {
		if (operatorSelected) {
			Object oldValue = event.getOldValue();
			Object newValue = event.getNewValue();
			log.debug(" Editado " + extPerformedWorks.get(event.getRowIndex()).getBobinaN());
			extPerformedWorks.get(event.getRowIndex()).setProdOperator(selectedOperator);
			if (newValue != null && !newValue.equals(oldValue)) {
				FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Operario seleccionado ", "" + newValue);
				FacesContext.getCurrentInstance().addMessage(null, msg);
			}
			operatorSelected = false;
			selectedOperator = null;
			selectedOperatorStr = "";
		}
	}

	public void handleOperatorSelection(SelectEvent event) {
		if (selectedOperatorStr != null) {
			operatorSelected = true;
			for (ProdOperator operator : operatorsAutocomp) {
				if (selectedOperatorStr.equalsIgnoreCase(operator.getFirstname() + " " + operator.getLastname())) {
					selectedOperator = operator;
					log.debug("selected operator " + selectedOperator);
				}
			}
		}
	}

	public List<String> completeOperator(String query) {
		List<String> result = new ArrayList<String>();
		operatorsAutocomp = produccionService.getOperators(query);
		for (ProdOperator operator : operatorsAutocomp) {
			result.add(operator.getFirstname() + " " + operator.getLastname());
		}
		return result;
	}

	public void rowSelected(SelectEvent event) {
		log.info("Orden de prod seleccionado " + selectedOp.getId());
		for (TipoMaterial tipo : TipoMaterial.values()) {
			if (selectedOp.getItem().getDensidad() == tipo.getValor()) {
				tipoMaterial = tipo;
			}
		}
	}

	public void rowUnselected(SelectEvent event) {
		log.info("Orden de prod deseleccionado ");
	}

	@PostConstruct
	public void initialize() {
		log.info("Initializing OrdenVentasBenan");
		HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
		state = request.getParameter("state");
		Long stateL = null;
		if (state != null && !state.isEmpty()) {
			stateL = Long.valueOf(state);
			setEstadoFiltro(produccionService.getEstadoProduccionById(stateL));
		}
		ordenesProd = produccionService.getOrdenProdByState(stateL);
		filteredOrdenProds = new ArrayList<OrdenProduccion>();
		filteredOrdenProds.addAll(ordenesProd);
		initializeSubMenu();
	}

	/**
	 * Esta funcion guarda la formula y se lo agrega a la orden de produccion.
	 * 
	 * @param event
	 */
	public void saveFormula(ActionEvent event) {
		if (selectedId != null && !selectedId.equals(selectedOp.getId())) {
			for (OrdenProduccion op : ordenesProd) {
				if (op.getId().equals(selectedId)) {
					selectedOp = op;
				}
			}
		}

		formulaBean.saveFormulaMps();
		if (RequestContext.getCurrentInstance().getCallbackParams().get("isValid") != null
				&& (boolean) RequestContext.getCurrentInstance().getCallbackParams().get("isValid")) {
			selectedOp.setFormula(formulaBean.getSelectedFormula());
			produccionService.updateOp(selectedOp);
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Formula", "Guardad satisfactoriamente");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}
	}

	public void saveAsNewFormula(ActionEvent event) {

		if (!selectedId.equals(selectedOp.getId())) {
			for (OrdenProduccion op : ordenesProd) {
				if (op.getId().equals(selectedId)) {
					selectedOp = op;
				}
			}
		}

		formulaBean.saveAsNewFormula(event);
		if (RequestContext.getCurrentInstance().getCallbackParams().get("isValid") != null
				&& (boolean) RequestContext.getCurrentInstance().getCallbackParams().get("isValid")) {
			selectedOp.setFormula(formulaBean.getSelectedFormula());
			produccionService.updateOp(selectedOp);
			log.debug("Save as new formula");
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Formula", "Guardad satisfactoriamente");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}
	}

	public void deleteExtrusionWork(Long id) {
		log.debug("Deleting " + id);
		for (ExtPerformedWork work : extPerformedWorks) {
			if (work.getId() != null && work.getId().equals(id)) {
				extPerformedWorks.remove(work);
				break;
			}
		}
	}

	public void deleteImpWork(Long id) {
		log.debug("Deleting " + id);
		for (ImpPerformedWork work : impPerformedWorks) {
			if (work.getId() != null && work.getId().equals(id)) {
				impPerformedWorks.remove(work);
				break;
			}
		}
	}

	public void deleteConfWork(Long id) {
		log.debug("Deleting " + id);
		for (ConfPerformedWork work : confPerformedWorks) {
			if (work.getId() != null && work.getId().equals(id)) {
				confPerformedWorks.remove(work);
				break;
			}
		}
	}

	public void deleteExtrusionScrap(Long id) {
		log.debug("Deleting Scrap" + id);
		for (ExtProdScrap scrap : extScrap) {
			if (scrap.getId() != null && scrap.getId().equals(id)) {
				extScrap.remove(scrap);
				RequestContext reqContext = RequestContext.getCurrentInstance();
				reqContext.update("dialogForm:prodSpecs:extrusionTabs:extScrapPanelId");
				break;
			}
		}
	}

	public void deleteImpresionScrap(Long id) {
		log.debug("Deleting Scrap" + id);
		for (ImpProdScrap scrap : impScrap) {
			if (scrap.getId() != null && scrap.getId().equals(id)) {
				impScrap.remove(scrap);
				RequestContext.getCurrentInstance().update("dialogForm:prodSpecs:impresionTabs:impScrapPanelId");
				break;
			}
		}
	}

	public void deleteConfeccionScrap(Long id) {
		log.debug("Deleting Scrap" + id);
		for (ConfProdScrap scrap : confScrap) {
			if (scrap.getId() != null && scrap.getId().equals(id)) {
				confScrap.remove(scrap);
				RequestContext.getCurrentInstance().update("dialogForm:prodSpecs:confeccionTabs:confScrapPanelId");
				break;
			}
		}
	}

	public void extrusionDone(ActionEvent event) {
		if (!selectedId.equals(selectedOp.getId())) {
			for (OrdenProduccion op : ordenesProd) {
				if (op.getId().equals(selectedId)) {
					selectedOp = op;
				}
			}
		}
		if (selectedOp.getItem().getImpresion()) {
			selectedOp.setEstadoProduccion(produccionService.getEstadoProduccionById(com.ape.mapsa.common.constants.EstadoProduccion.IN_IMPRESSION
					.getId()));
		} else {
			selectedOp.setEstadoProduccion(produccionService.getEstadoProduccionById(com.ape.mapsa.common.constants.EstadoProduccion.IN_CONFECTION
					.getId()));
		}
		selectedOp.getExtrusion().setFinalizationDate(new Date());
		produccionService.updateExtrusion(selectedOp.getExtrusion());
		produccionService.updateOp(selectedOp);
		FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Extrusion Finalizada", "");
		FacesContext.getCurrentInstance().addMessage(null, msg);
		RequestContext.getCurrentInstance().update("dialogForm:dataTable");
	}

	public void impresionDone(ActionEvent event) {
		if (!selectedId.equals(selectedOp.getId())) {
			for (OrdenProduccion op : ordenesProd) {
				if (op.getId().equals(selectedId)) {
					selectedOp = op;
				}
			}
		}
		selectedOp.getImpresions().setFinalizationDate(new Date());
		produccionService.updateImpresion(selectedOp.getImpresions());
		selectedOp.setEstadoProduccion(produccionService.getEstadoProduccionById(com.ape.mapsa.common.constants.EstadoProduccion.IN_CONFECTION
				.getId()));
		produccionService.updateOp(selectedOp);
		FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Impresion Finalizada", "");
		FacesContext.getCurrentInstance().addMessage(null, msg);
		RequestContext.getCurrentInstance().update("dialogForm:dataTable");
	}

	public void confeccionDone(ActionEvent event) {
		if (!selectedId.equals(selectedOp.getId())) {
			for (OrdenProduccion op : ordenesProd) {
				if (op.getId().equals(selectedId)) {
					selectedOp = op;
				}
			}
		}
		selectedOp.setEstadoProduccion(produccionService.getEstadoProduccionById(com.ape.mapsa.common.constants.EstadoProduccion.DONE.getId()));
		selectedOp.getConfeccions().setFinalizationDate(new Date());
		produccionService.updateConfeccion(selectedOp.getConfeccions());
		produccionService.updateOp(selectedOp);
		renderPerformedWork = false;
		FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Confeccion Finalizada", "");
		FacesContext.getCurrentInstance().addMessage(null, msg);
		RequestContext reqContext = RequestContext.getCurrentInstance();
		reqContext.update("dialogForm:detailsPanel");
		RequestContext.getCurrentInstance().update("dialogForm:dataTable");
	}

	public void addExtrusionScrap(ActionEvent event) {

		log.debug("adding new Scrap");
		ExtProdScrap e = new ExtProdScrap();
		scrapTemporalId = scrapTemporalId - 1;
		e.setId(scrapTemporalId);
		if (selectedId.equals(selectedOp.getId())) {
			extScrap.add(e);
			e.setExtrusion(selectedOp.getExtrusion());
		} else {
			for (OrdenProduccion op : ordenesProd) {
				if (op.getId().equals(selectedId)) {
					selectedOp = op;
					e.setExtrusion(selectedOp.getExtrusion());
					extScrap.add(e);
				}
			}
		}

	}

	public void addImpresionScrap(ActionEvent event) {
		log.debug("adding new Scrap");
		ImpProdScrap e = new ImpProdScrap();
		impScrapTemporalId = impScrapTemporalId - 1;
		e.setId(impScrapTemporalId);
		if (selectedId.equals(selectedOp.getId())) {
			impScrap.add(e);
			e.setImpresion(selectedOp.getImpresions());
		} else {
			for (OrdenProduccion op : ordenesProd) {
				if (op.getId().equals(selectedId)) {
					selectedOp = op;
					e.setImpresion(selectedOp.getImpresions());
					impScrap.add(e);
				}
			}
		}
	}

	public void addConfeccionScrap(ActionEvent event) {
		log.debug("adding new Scrap");
		ConfProdScrap e = new ConfProdScrap();
		confScrapTemporalId = confScrapTemporalId - 1;
		e.setId(confScrapTemporalId);
		if (selectedId.equals(selectedOp.getId())) {
			e.setConfeccion(selectedOp.getConfeccions());
			confScrap.add(e);
		} else {
			for (OrdenProduccion op : ordenesProd) {
				if (op.getId().equals(selectedId)) {
					selectedOp = op;
					e.setConfeccion(selectedOp.getConfeccions());
					confScrap.add(e);
				}
			}
		}
	}

	public void rowExtEdited(RowEditEvent event) {
		log.debug("Editing Row " + event.getObject());
	}

	public void addExtrusionWork(ActionEvent event) {
		log.debug("adding new work row");
		ExtPerformedWork e = new ExtPerformedWork();
		temporalId = temporalId - 1;
		e.setId(temporalId);
		if (selectedId.equals(selectedOp.getId())) {
			extPerformedWorks.add(e);
			e.setExtrusion(selectedOp.getExtrusion());
		} else {
			for (OrdenProduccion op : ordenesProd) {
				if (op.getId().equals(selectedId)) {
					selectedOp = op;
					e.setExtrusion(selectedOp.getExtrusion());
					extPerformedWorks.add(e);
				}
			}
		}
	}

	public void addImpresionWork(ActionEvent event) {
		log.debug("adding new work row");
		ImpPerformedWork e = new ImpPerformedWork();
		impTemporalId = impTemporalId - 1;
		e.setId(impTemporalId);
		if (selectedId.equals(selectedOp.getId())) {
			impPerformedWorks.add(e);
			e.setImpresion(selectedOp.getImpresions());
		} else {
			for (OrdenProduccion op : ordenesProd) {
				if (op.getId().equals(selectedId)) {
					selectedOp = op;
					e.setImpresion(selectedOp.getImpresions());
					impPerformedWorks.add(e);
				}
			}
		}
	}

	public void addConfeccionWork(ActionEvent event) {
		log.debug("adding new work row");
		ConfPerformedWork e = new ConfPerformedWork();
		confTemporalId = confTemporalId - 1;
		e.setId(confTemporalId);
		if (selectedId.equals(selectedOp.getId())) {
			confPerformedWorks.add(e);
			e.setConfeccion(selectedOp.getConfeccions());
		} else {
			for (OrdenProduccion op : ordenesProd) {
				if (op.getId().equals(selectedId)) {
					selectedOp = op;
					e.setConfeccion(selectedOp.getConfeccions());
					confPerformedWorks.add(e);
				}
			}
		}
	}

	public void saveExtrusionWork(ActionEvent event) {
		if (!selectedOp.getId().equals(selectedId)) {
			for (OrdenProduccion op : ordenesProd) {
				if (op.getId().equals(selectedId)) {
					selectedOp = op;
					break;
				}
			}
		}
		List<ExtPerformedWork> actualPerformedWorks = new ArrayList<ExtPerformedWork>();
		List<ExtProdScrap> actualScraps = new ArrayList<ExtProdScrap>();

		// FRESH ORDEN DE PRODUCCION
		actualPerformedWorks.addAll(produccionService.getExtrusionPerformedWorks(selectedOp.getExtrusion()));
		actualScraps.addAll(produccionService.getExtrusionScraps(selectedOp.getExtrusion()));
		boolean updated = false;

		// ITERATE OVER PERFORMED WORKS AND SVE OR UPDATE
		for (ExtPerformedWork performedWork : extPerformedWorks) {
			if (!actualPerformedWorks.contains(performedWork)) {
				log.debug("Nueo o modificado, id:" + performedWork.getId());
				if (performedWork.getId() == null || (performedWork.getId() != null && performedWork.getId().longValue() < 0)) {
					log.debug("Nuevo ");
					performedWork.setId(null);
					performedWork.setExtrusion(selectedOp.getExtrusion());
					produccionService.saveExtrusionPerformedWork(performedWork);
					selectedOp.getExtrusion().setTotalMts(selectedOp.getExtrusion().getTotalMts() + performedWork.getMeters());
					selectedOp.getExtrusion().setTotalKilos(selectedOp.getExtrusion().getTotalKilos() + performedWork.getPeso());
					selectedOp.getExtrusion().setTotalBobinas(selectedOp.getExtrusion().getTotalBobinas() + 1);
					produccionService.updateExtrusion(selectedOp.getExtrusion());
				} else {
					updated = true;
					log.debug("Modificado guardarndo...");
					produccionService.updateExtrusionPerformedWork(performedWork);
				}
			}
		}
		// CHECK FOR DELETED PERFOMRED WORKS
		for (ExtPerformedWork performedWork : actualPerformedWorks) {
			boolean deleted = true;
			for (ExtPerformedWork performedWork2 : extPerformedWorks) {
				if (performedWork.getId().equals(performedWork2.getId())) {
					deleted = false;
					break;
				}
			}
			if (deleted) {
				produccionService.deleteExtrusionPerformedWork(performedWork);
			}
		}

		// ITERATE OVER SCRAPS AND SAVE OR UPDATE
		for (ExtProdScrap scrap : extScrap) {
			if (!actualScraps.contains(scrap)) {
				log.debug("Scrap Nuevo o modificado, id:" + scrap.getId());
				if (scrap.getId() == null || (scrap.getId() != null && scrap.getId().longValue() < 0)) {
					log.debug("Scrap Nuevo ");
					scrap.setId(null);
					selectedOp.getExtrusion().setTotalScrap(selectedOp.getExtrusion().getTotalScrap() + scrap.getKg());
					produccionService.saveProdExtrusionScrap(scrap);
					produccionService.updateExtrusion(selectedOp.getExtrusion());
				} else {
					updated = true;
					log.debug("Scrap modificado guardando ...");
					produccionService.updateProdExtrusionScrap(scrap);
				}
			}
		}
		// CHECK FOR DELETED SCRAPS
		for (ExtProdScrap scrap : actualScraps) {
			boolean deleted = true;
			for (ExtProdScrap scrap2 : extScrap) {
				if (scrap.getId().equals(scrap2.getId())) {
					deleted = false;
					break;
				}
			}
			if (deleted) {
				produccionService.deleteProdExtrusionScrap(scrap);
			}
		}
		if (updated) {
			float totalMetros = 0;
			float totalKilos = 0;
			int totalBobinas = 0;
			float totalScrap = 0;
			for (ExtPerformedWork performedWork : extPerformedWorks) {
				totalMetros = totalMetros + performedWork.getMeters();
				totalKilos = totalKilos + performedWork.getPeso();
				totalBobinas++;
			}
			for (ExtProdScrap scrap : extScrap) {
				totalScrap = totalScrap + scrap.getKg();
				log.debug("Total scrap: " + totalScrap);
			}
			selectedOp.getExtrusion().setTotalKilos(totalKilos);
			selectedOp.getExtrusion().setTotalMts(totalMetros);
			selectedOp.getExtrusion().setTotalBobinas(totalBobinas);
			selectedOp.getExtrusion().setTotalScrap(totalScrap);
			produccionService.updateExtrusion(selectedOp.getExtrusion());
		}

		FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Extrusion", "Los trabajos fueron guardados satisfactoriamente.");
		FacesContext.getCurrentInstance().addMessage(null, msg);

	}

	public void saveConfeccionWork(ActionEvent event) {
		if (!selectedOp.getId().equals(selectedId)) {
			for (OrdenProduccion op : ordenesProd) {
				if (op.getId().equals(selectedId)) {
					selectedOp = op;
					break;
				}
			}
		}
		List<ConfPerformedWork> actualPerformedWorks = new ArrayList<ConfPerformedWork>();
		List<ConfProdScrap> actualScraps = new ArrayList<ConfProdScrap>();

		// FRESH ORDEN DE PRODUCCION
		actualPerformedWorks.addAll(produccionService.getConfectionPerformedWorks(selectedOp.getConfeccions()));
		actualScraps.addAll(produccionService.getConfectionScraps(selectedOp.getConfeccions()));
		boolean updated = false;

		// ITERATE OVER PERFORMED WORKS AND SVE OR UPDATE
		for (ConfPerformedWork performedWork : confPerformedWorks) {
			if (!actualPerformedWorks.contains(performedWork)) {
				log.debug("Nueo o modificado, id:" + performedWork.getId());
				if (performedWork.getId() == null || (performedWork.getId() != null && performedWork.getId().longValue() < 0)) {
					log.debug("Nuevo ");
					performedWork.setId(null);
					performedWork.setConfeccion(selectedOp.getConfeccions());
					produccionService.saveConfeccionPerformedWork(performedWork);
					selectedOp.getConfeccions().setTotalBolsas(selectedOp.getConfeccions().getTotalBolsas() + performedWork.getBolsas());
					selectedOp.getConfeccions().setTotalBultos(selectedOp.getConfeccions().getTotalBultos() + performedWork.getBultos());
					selectedOp.getConfeccions().setTotalBobinas(selectedOp.getConfeccions().getTotalBobinas() + 1);
					produccionService.updateConfeccion(selectedOp.getConfeccions());
				} else {
					updated = true;
					log.debug("Modificado guardarndo...");
					produccionService.updateConfeccionPerformedWork(performedWork);
				}
			}
		}
		// CHECK FOR DELETED PERFOMRED WORKS
		for (ConfPerformedWork performedWork : actualPerformedWorks) {
			boolean deleted = true;
			for (ConfPerformedWork performedWork2 : confPerformedWorks) {
				if (performedWork.getId().equals(performedWork2.getId())) {
					deleted = false;
					break;
				}
			}
			if (deleted) {
				produccionService.deleteConfeccionPerformedWork(performedWork);
			}
		}

		// ITERATE OVER SCRAPS AND SAVE OR UPDATE
		for (ConfProdScrap scrap : confScrap) {
			if (!actualScraps.contains(scrap)) {
				log.debug("Scrap Nuevo o modificado, id:" + scrap.getId());
				if (scrap.getId() == null || (scrap.getId() != null && scrap.getId().longValue() < 0)) {
					log.debug("Scrap Nuevo ");
					scrap.setId(null);
					selectedOp.getConfeccions().setTotalScrap(selectedOp.getConfeccions().getTotalScrap() + scrap.getKg());
					produccionService.saveProdConfeccionScrap(scrap);
					produccionService.updateConfeccion(selectedOp.getConfeccions());
				} else {
					updated = true;
					log.debug("Scrap modificado guardando ...");
					produccionService.updateProdConfeccionScrap(scrap);
				}
			}
		}
		// CHECK FOR DELETED SCRAPS
		for (ConfProdScrap scrap : actualScraps) {
			boolean deleted = true;
			for (ConfProdScrap scrap2 : confScrap) {
				if (scrap.getId().equals(scrap2.getId())) {
					deleted = false;
					break;
				}
			}
			if (deleted) {
				produccionService.deleteProdConfeccionScrap(scrap);
			}
		}
		if (updated) {
			int totalBolsas = 0;
			int totalBultos = 0;
			int totalBobinas = 0;
			float totalScrap = 0;
			for (ConfPerformedWork performedWork : confPerformedWorks) {
				totalBolsas = totalBolsas + performedWork.getBolsas();
				totalBultos = totalBultos + performedWork.getBultos();
				totalBobinas++;
			}
			for (ConfProdScrap scrap : confScrap) {
				totalScrap = totalScrap + scrap.getKg();
				log.debug("Total scrap: " + totalScrap);
			}
			selectedOp.getConfeccions().setTotalBolsas(totalBolsas);
			selectedOp.getConfeccions().setTotalBobinas(totalBobinas);
			selectedOp.getConfeccions().setTotalBultos(totalBultos);
			selectedOp.getConfeccions().setTotalScrap(totalScrap);
			produccionService.updateConfeccion(selectedOp.getConfeccions());
		}

		FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Confección", "Los trabajos fueron guardados satisfactoriamente.");
		FacesContext.getCurrentInstance().addMessage(null, msg);

	}

	public void saveImpresionWork(ActionEvent event) {
		if (!selectedOp.getId().equals(selectedId)) {
			for (OrdenProduccion op : ordenesProd) {
				if (op.getId().equals(selectedId)) {
					selectedOp = op;
					break;
				}
			}
		}
		List<ImpPerformedWork> actualPerformedWorks = new ArrayList<ImpPerformedWork>();
		List<ImpProdScrap> actualScraps = new ArrayList<ImpProdScrap>();

		// FRESH ORDEN DE PRODUCCION
		actualPerformedWorks.addAll(produccionService.getImpresionPerformedWorks(selectedOp.getImpresions()));
		actualScraps.addAll(produccionService.getImpresionScraps(selectedOp.getImpresions()));
		boolean updated = false;

		// ITERATE OVER PERFORMED WORKS AND SVE OR UPDATE
		for (ImpPerformedWork performedWork : impPerformedWorks) {
			if (!actualPerformedWorks.contains(performedWork)) {
				log.debug("Nueo o modificado, id:" + performedWork.getId());
				if (performedWork.getId() == null || (performedWork.getId() != null && performedWork.getId().longValue() < 0)) {
					log.debug("Nuevo ");
					performedWork.setId(null);
					performedWork.setImpresion(selectedOp.getImpresions());
					produccionService.saveImpresionPerformedWork(performedWork);
					selectedOp.getExtrusion().setTotalMts(selectedOp.getExtrusion().getTotalMts() + performedWork.getMeters());
					selectedOp.getExtrusion().setTotalKilos(selectedOp.getExtrusion().getTotalKilos() + performedWork.getPeso());
					selectedOp.getExtrusion().setTotalBobinas(selectedOp.getExtrusion().getTotalBobinas() + 1);
					produccionService.updateExtrusion(selectedOp.getExtrusion());
				} else {
					updated = true;
					log.debug("Modificado guardarndo...");
					produccionService.updateImpresionPerformedWork(performedWork);
				}
			}
		}
		// CHECK FOR DELETED PERFOMRED WORKS
		for (ImpPerformedWork performedWork : actualPerformedWorks) {
			boolean deleted = true;
			for (ImpPerformedWork performedWork2 : impPerformedWorks) {
				if (performedWork.getId().equals(performedWork2.getId())) {
					deleted = false;
					break;
				}
			}
			if (deleted) {
				produccionService.deleteImpresionPerformedWork(performedWork);
			}
		}

		// ITERATE OVER SCRAPS AND SAVE OR UPDATE
		for (ImpProdScrap scrap : impScrap) {
			if (!actualScraps.contains(scrap)) {
				log.debug("Scrap Nuevo o modificado, id:" + scrap.getId());
				if (scrap.getId() == null || (scrap.getId() != null && scrap.getId().longValue() < 0)) {
					log.debug("Scrap Nuevo ");
					scrap.setId(null);
					selectedOp.getImpresions().setTotalScrap(selectedOp.getImpresions().getTotalScrap() + scrap.getKg());
					produccionService.saveProdImpresionScrap(scrap);
					produccionService.updateImpresion(selectedOp.getImpresions());
				} else {
					updated = true;
					log.debug("Scrap modificado guardando ...");
					produccionService.updateProdImpresionScrap(scrap);
				}
			}
		}
		// CHECK FOR DELETED SCRAPS
		for (ImpProdScrap scrap : actualScraps) {
			boolean deleted = true;
			for (ImpProdScrap scrap2 : impScrap) {
				if (scrap.getId().equals(scrap2.getId())) {
					deleted = false;
					break;
				}
			}
			if (deleted) {
				produccionService.deleteProdImpresionScrap(scrap);
			}
		}
		if (updated) {
			float totalMetros = 0;
			float totalKilos = 0;
			int totalBobinas = 0;
			float totalScrap = 0;
			for (ImpPerformedWork performedWork : impPerformedWorks) {
				totalMetros = totalMetros + performedWork.getMeters();
				totalKilos = totalKilos + performedWork.getPeso();
				totalBobinas++;
			}
			for (ImpProdScrap scrap : impScrap) {
				totalScrap = totalScrap + scrap.getKg();
				log.debug("Total scrap: " + totalScrap);
			}
			selectedOp.getImpresions().setTotalKilos(totalKilos);
			selectedOp.getImpresions().setTotalMts(totalMetros);
			selectedOp.getImpresions().setTotalBobinas(totalBobinas);
			selectedOp.getImpresions().setTotalScrap(totalScrap);
			produccionService.updateImpresion(selectedOp.getImpresions());
		}

		FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Impresión", "Los trabajos fueron guardados satisfactoriamente.");
		FacesContext.getCurrentInstance().addMessage(null, msg);

	}

	private void initializeSubMenu() {
		FacesContext context = FacesContext.getCurrentInstance();
		Submenu sm = new Submenu();
		sm.setLabel("Ordenes de Produccion");
		sm.setId("opSubMenu");
		sm.setIcon("ui-icon-pin-s");

		MenuItem menuItem = new MenuItem();
		menuItem.setValue("Ver Detalles");
		menuItem.setIcon("ui-icon-document-b");
		menuItem.setId("viewProdDetailsId");
		MethodExpression actionListener = context.getApplication().getExpressionFactory()
				.createMethodExpression(context.getELContext(), "#{ordenProdMB.showDetails}", null, new Class[] { ActionEvent.class });
		menuItem.addActionListener(new MethodExpressionActionListener(actionListener));

		sm.getChildren().add(menuItem);

		menuItem = new MenuItem();
		menuItem.setValue("Comentarios");
		menuItem.setIcon("ui-icon-comment");
		menuItem.setId("viewCommentsId");
		MethodExpression commentsAct = context.getApplication().getExpressionFactory()
				.createMethodExpression(context.getELContext(), "#{ordenProdMB.showComments}", null, new Class[] { ActionEvent.class });
		menuItem.addActionListener(new MethodExpressionActionListener(commentsAct));

		sm.getChildren().add(menuItem);

		menuItem = new MenuItem();
		menuItem.setId("printProdSpecs");
		menuItem.setIcon("ui-icon-print");
		menuItem.setAjax(false);
		menuItem.setValue("Especificaciones");
		MethodExpression saveAl = context.getApplication().getExpressionFactory()
				.createMethodExpression(context.getELContext(), "#{ordenProdMB.printProdSpecs}", null, new Class[] { ActionEvent.class });
		menuItem.addActionListener(new MethodExpressionActionListener(saveAl));
		archivo.getChildren().add(menuItem);

		menuItem = new MenuItem();
		menuItem.setId("performedWorkMenu");
		menuItem.setIcon("ui-icon-wrench");
		menuItem.setValue("Trabajos realizados");
		menuItem.setProcess("@this");
		MethodExpression viewPerformedWork = context.getApplication().getExpressionFactory()
				.createMethodExpression(context.getELContext(), "#{ordenProdMB.showPerformedWork}", null, new Class[] { ActionEvent.class });
		menuItem.addActionListener(new MethodExpressionActionListener(viewPerformedWork));
		sm.getChildren().add(menuItem);

		menuModel.addSubmenu(sm);
	}

	private void getActions(List<UserRole> roles, OrdenProduccion orden) {
		List<ProdAction> actionsList = new ArrayList<>();
		for (UserRole userRole : roles) {
			if (userRole.getRole().getRoleName().equals("mapsa-jefe-desarollo") && orden.getEstadoProduccion().getId() == 1) {
				actionsList.add(ProdAction.APROBAR_FACTIBILIDAD);
				actionsList.add(ProdAction.RECHAZAR);
			} else if (userRole.getRole().getRoleName().equalsIgnoreCase("mapsa-jefe-calidad") && orden.getEstadoProduccion().getId() == 2) {
				actionsList.add(ProdAction.APROBAR_CALIDAD);
				actionsList.add(ProdAction.RECHAZAR);
			}
		}
		setActions(actionsList.toArray(new ProdAction[0]));
	}

	public void performAction() {
		log.debug("Realizando " + getAction().toString());
		FacesContext context = FacesContext.getCurrentInstance();
		try {
			if (action.equals(ProdAction.RECHAZAR) && comment.isEmpty()) {
				RequestContext.getCurrentInstance().execute("commentDialog.show();");
				return;
			}
			EstadoProduccion estadoProd = produccionService.getEstadoProduccionById(action.getConsequence());
			selectedOp.setEstadoProduccion(estadoProd);

			if (!comment.isEmpty()) {
				OpComment commentToSave = new OpComment();
				commentToSave.setAuthor(userBean.getEmail());
				commentToSave.setOrdenProduccionBean(selectedOp);
				commentToSave.setType(1);
				commentToSave.setComment(comment);
				produccionService.saveComment(commentToSave);
			}

			produccionService.updateOrdenProd(selectedOp);
			renderOpDetails = false;
			renderOpComments = false;
			comment = "";
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Estado actualizado a: ", estadoProd.getDescripcion());
			context.addMessage(null, msg);
			homeBean.initilizeMenu();
			RequestContext.getCurrentInstance().update("inboxMenuForm:inboxMenuBar");
			if (state != null) {
				initialize();
			}
		} catch (Exception x) {
			log.error(x);
			comment = "";
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Que verguenza", "No se pudo realizar la accion, reporte la situacion.");
			context.addMessage("growl", msg);
		}
	}

	public void cancelEdition() {
		log.debug("Cancelando edicion del orden de producto");
		renderOpDetails = false;
		comment = null;
	}

	public void printProdSpecs(ActionEvent event) {
		log.info("Showing prodSpecs");
		FacesContext context = FacesContext.getCurrentInstance();
		if (selectedOp != null) {
			if (isProductQualityApproved()) {
				try {
					long start = System.currentTimeMillis();

					String reportPath = FacesContext.getCurrentInstance().getExternalContext().getRealPath("resources/reports/prod_specs.jasper");

					HashMap<String, Object> parameters = new HashMap<String, Object>();
					parameters.put("opid", selectedOp.getId());
					parameters.put("creationDate", selectedOp.getFechaCreacion());
					parameters.put("pedido", selectedOp.getPedidoVenta().getId());
					parameters.put("cliente", selectedOp.getPedidoVenta().getClienteBean().getNombre());
					parameters.put("fechaEntrega", selectedOp.getFechaEntrega());
					parameters.put("extFechaIni", selectedOp.getExtrusion().getFechaInicio());
					parameters.put("extrusora", selectedOp.getExtrusion().getMaquina().getMaqCodigo());
					parameters.put("extFechaFin", selectedOp.getExtrusion().getFechaFin());
					parameters.put("ancho", selectedOp.getItem().getAncho());
					parameters.put("largo", selectedOp.getItem().getLargo());
					parameters.put("tipoBolsa", selectedOp.getItem().getItemTipo().getDescripcion());
					parameters.put("espesor", selectedOp.getItem().getEspesor());
					parameters.put("tratado", selectedOp.getItem().getTratado());
					parameters.put("bobinas", selectedOp.getExtrusion().getBobinas());
					parameters.put("kilos", selectedOp.getExtrusion().getKilos());
					parameters.put("metros", selectedOp.getExtrusion().getMetros());
					parameters.put("pesoBolsa", selectedOp.getExtrusion().getPesoBolsa());
					parameters.put("grm2", selectedOp.getExtrusion().getGrm2());
					parameters.put("gramaje", selectedOp.getExtrusion().getGramaje());
					parameters.put("tipoMaterial", TipoMaterial.getTipoMaterialByValue(selectedOp.getItem().getDensidad()));

					parameters.put("totalKg", selectedOp.getExtrusion().getTotalKilos());
					parameters.put("totalBobinas", selectedOp.getExtrusion().getTotalBobinas());
					parameters.put("totalMts", selectedOp.getExtrusion().getTotalMts());
					parameters.put("totalScrap", selectedOp.getExtrusion().getTotalScrap());

					// DATOS DE IMPRESION
					parameters.put("impMaquina", selectedOp.getImpresions().getMaquina().getMaqCodigo());
					parameters.put("impFechaIni", selectedOp.getImpresions().getFechaInicio());
					parameters.put("impFechaFin", selectedOp.getImpresions().getFechaFin());
					parameters.put("impTotalBobinas", selectedOp.getImpresions().getTotalBobinas());
					parameters.put("impTotalScrap", selectedOp.getImpresions().getTotalScrap());
					parameters.put("impTotalKg", selectedOp.getImpresions().getTotalKilos());
					parameters.put("impTotalMts", selectedOp.getImpresions().getTotalMts());
					parameters.put("impText", selectedOp.getItem().getDepItemPrintSpec().getText());
					parameters.put("impFrente", selectedOp.getItem().getDepItemPrintSpec().getFrente());
					parameters.put("impDorso", selectedOp.getItem().getDepItemPrintSpec().getDorso());
					parameters.put("impCilindro", selectedOp.getItem().getDepItemPrintSpec().getCilindro());
					parameters.put("impCantColor", selectedOp.getItem().getDepItemPrintSpec().getCantColor());

					// EXTRUSION WORK
					List<ExtPerformedWork> preformedWorks = produccionService.getExtrusionPerformedWorks(selectedOp.getExtrusion());
					int size = preformedWorks.size();

					for (int i = 0; i <= 20 - size; i++) {
						preformedWorks.add(new ExtPerformedWork());
					}
					List<ExtPerformedWork> extrusionCol1 = preformedWorks.subList(0, 10);
					List<ExtPerformedWork> extrusionCol2 = preformedWorks.subList(10, 20);
					// IMPRESION WORK
					List<ImpPerformedWork> impPreformedWorks = produccionService.getImpresionPerformedWorks(selectedOp.getImpresions());
					int impSize = impPreformedWorks.size();

					for (int i = 0; i <= 20 - impSize; i++) {
						impPreformedWorks.add(new ImpPerformedWork());
					}
					List<ImpPerformedWork> impCol1 = impPreformedWorks.subList(0, 10);
					List<ImpPerformedWork> impCol2 = impPreformedWorks.subList(10, 20);

					JasperReport masterReport = (JasperReport) JRLoader.loadObject(new File(reportPath));

					parameters.put("EXTRUSION_REPORT",
							FacesContext.getCurrentInstance().getExternalContext().getRealPath("resources/reports/extrusion.jasper"));
					parameters.put("EXTRUSION_COL1_REPORT",
							FacesContext.getCurrentInstance().getExternalContext().getRealPath("resources/reports/extrusion_col1.jasper"));
					parameters.put("EXTRUSION_COL2_REPORT",
							FacesContext.getCurrentInstance().getExternalContext().getRealPath("resources/reports/extrusion_col2.jasper"));
					parameters.put("IMPRESION_REPORT",
							FacesContext.getCurrentInstance().getExternalContext().getRealPath("resources/reports/impresion.jasper"));
					parameters.put("IMPRESION_COL1_REPORT",
							FacesContext.getCurrentInstance().getExternalContext().getRealPath("resources/reports/extrusion_col1.jasper"));
					parameters.put("IMPRESION_COL2_REPORT",
							FacesContext.getCurrentInstance().getExternalContext().getRealPath("resources/reports/extrusion_col2.jasper"));
					parameters.put("HEADER_REPORT",
							FacesContext.getCurrentInstance().getExternalContext().getRealPath("resources/reports/prod_specs_header.jasper"));

					parameters.put("EXTRUSION_COL1_DATA", extrusionCol1);
					parameters.put("EXTRUSION_COL2_DATA", extrusionCol2);
					parameters.put("IMP_COL1_DATA", impCol1);
					parameters.put("IMP_COL2_DATA", impCol2);

					JasperPrint jasperPrint = JasperFillManager.fillReport(masterReport, parameters, new JREmptyDataSource());
					HttpServletResponse httpServletResponse = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext()
							.getResponse();
					SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy_HH:mm");
					httpServletResponse.addHeader("Content-disposition",
							"attachment; filename=" + selectedOp.getId() + "_especificaionces_" + sdf.format(new Date()) + ".pdf");
					ServletOutputStream servletOutputStream = httpServletResponse.getOutputStream();
					JasperExportManager.exportReportToPdfStream(jasperPrint, servletOutputStream);
					FacesContext.getCurrentInstance().responseComplete();
					log.debug("Filling time : " + (System.currentTimeMillis() - start));
				} catch (JRException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			} else {
				FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Orden de producción", "No esta aun en un estado aprobado.");
				context.addMessage(null, msg);
			}
		} else {
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Selecciono nula",
					"Debe seleccionar una orden de trabajo para realizar esta operación.");
			context.addMessage(null, msg);
		}
	}

	public void showPerformedWork(ActionEvent event) {
		log.info("Showing work");
		FacesContext context = FacesContext.getCurrentInstance();
		if (selectedOp != null) {
			if (isProductQualityApproved()) {
				log.debug("Prod order is ready to work");
				formulaBean.setSelectedFormula(null);
				formulaBean.setSelectedFormula(selectedOp.getFormula());
				log.debug("Selected Fromula: " + formulaBean.getSelectedFormula());
				if (formulaBean.getSelectedFormula() != null && formulaBean.getSelectedFormula().getId() != null) {
					log.debug("prod order has no formula, getting formula...");
					formulaBean.getSelectedFormula().setFormulaMps(produccionService.getMpForFormula(formulaBean.getSelectedFormula()));
				} else {
					selectedOp.setFormula(new Formula());
					formulaBean.setSelectedFormula(selectedOp.getFormula());
					log.debug("prod order has no formula");
				}
				renderOpComments = false;
				renderOpDetails = false;
				renderPerformedWork = true;
				selectedId = selectedOp.getId();
				RequestContext reqContext = RequestContext.getCurrentInstance();
				reqContext.update("dialogForm:detailsPanel");
				reqContext.scrollTo("dialogForm:detailsPanel");

				// Get extrusion work and scrap
				extPerformedWorks = new ArrayList<ExtPerformedWork>();
				extScrap = new ArrayList<ExtProdScrap>();
				List<ExtPerformedWork> performedWorks = produccionService.getExtrusionPerformedWorks(selectedOp.getExtrusion());
				List<ExtProdScrap> extrusionScrap = produccionService.getExtrusionScraps(selectedOp.getExtrusion());
				extPerformedWorks.addAll(performedWorks);
				extScrap.addAll(extrusionScrap);

				// Get Impression Work and scrap
				if (selectedOp.getItem().getImpresion()) {
					impPerformedWorks = new ArrayList<ImpPerformedWork>();
					impScrap = new ArrayList<ImpProdScrap>();
					List<ImpPerformedWork> impPerformedWorks = produccionService.getImpresionPerformedWorks(selectedOp.getImpresions());
					List<ImpProdScrap> impScrap = produccionService.getImpresionScraps(selectedOp.getImpresions());
					this.impPerformedWorks.addAll(impPerformedWorks);
					this.impScrap.addAll(impScrap);
				}

				// Get confection work and scrap
				confPerformedWorks = new ArrayList<ConfPerformedWork>();
				confScrap = new ArrayList<ConfProdScrap>();
				List<ConfPerformedWork> con = produccionService.getConfectionPerformedWorks(selectedOp.getConfeccions());
				List<ConfProdScrap> confectionScrap = produccionService.getConfectionScraps(selectedOp.getConfeccions());
				confPerformedWorks.addAll(con);
				confScrap.addAll(confectionScrap);
			} else {
				FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Estado",
						"La Orden de Produccion seleccionada no se encuentra en un estado de aprobacion.");
				context.addMessage(null, msg);
			}
		} else {
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Estado",
					"La Orden de Produccion seleccionada no se encuentra en un estado de aprobacion.");
			context.addMessage(null, msg);
		}
	}

	private boolean isProductQualityApproved() {
		if (selectedOp != null) {
			return selectedOp.getEstadoProduccion().getId().equals(com.ape.mapsa.common.constants.EstadoProduccion.IN_EXTRUSION.getId())
					|| selectedOp.getEstadoProduccion().getId().equals(com.ape.mapsa.common.constants.EstadoProduccion.CALIDAD_APROBADA.getId())
					|| selectedOp.getEstadoProduccion().getId().equals(com.ape.mapsa.common.constants.EstadoProduccion.IN_CONFECTION.getId())
					|| selectedOp.getEstadoProduccion().getId().equals(com.ape.mapsa.common.constants.EstadoProduccion.IN_IMPRESSION.getId())
					|| selectedOp.getEstadoProduccion().getId().equals(com.ape.mapsa.common.constants.EstadoProduccion.DONE.getId())
					|| selectedOp.getEstadoProduccion().getId().equals(com.ape.mapsa.common.constants.EstadoProduccion.RECHAZADO.getId());
			// TODO: si esta rechazado no se podra modificar nada
		}
		return false;
	}

	public void showComments(ActionEvent event) {
		log.info("Showing comments");
		renderOpComments = true;
		renderOpDetails = false;
		renderPerformedWork = false;
		FacesContext context = FacesContext.getCurrentInstance();
		if (selectedOp != null) {
			RequestContext reqContext = RequestContext.getCurrentInstance();
			reqContext.update("dialogForm:detailsPanel");
			reqContext.scrollTo("dialogForm:detailsPanel");
		} else {
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Selecciono nula",
					"Debe seleccionar una orden de trabajo para realizar esta operación.");
			context.addMessage(null, msg);
		}
	}

	public void showDetails(ActionEvent event) {
		log.info("Showing detials");
		FacesContext context = FacesContext.getCurrentInstance();
		if (selectedOp != null) {
			renderOpDetails = true;
			renderPerformedWork = false;
			renderOpComments = false;
			comment = "";
			getActions(userBean.getRoles(), selectedOp);
			RequestContext reqContext = RequestContext.getCurrentInstance();
			reqContext.update("dialogForm:detailsPanel");
			reqContext.scrollTo("dialogForm:detailsPanel");
		} else {
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Selecciono nula",
					"Debe seleccionar una orden de trabajo para realizar esta operación.");
			context.addMessage(null, msg);
		}
	}

	@Override
	public void save(ActionEvent event) {
		log.info("Guardando datos " + event.getSource());
	}

	@Override
	public void update(ActionEvent event) {
		log.info("Actualizando datos " + event.getSource());
		RequestContext.getCurrentInstance().update("dialogForm:dataTable");
	}

	@Override
	public void edit(ActionEvent event) {
		// TODO Auto-generated method stub
	}

	@Override
	public void create(ActionEvent event) {
		log.info("Creando nuevo OP " + event.getSource());
	}

	@Override
	public void delete(ActionEvent event) {
		log.info("Eliminando Orden de producto");
	}

	public List<OrdenProduccion> getFilteredOrdenProds() {
		return filteredOrdenProds;
	}

	public void setFilteredOrdenProds(List<OrdenProduccion> filteredOrdenProds) {
		this.filteredOrdenProds = filteredOrdenProds;
	}

	public MenuModel getMenuModel() {
		return menuModel;
	}

	public void setMenuModel(MenuModel menuModel) {
		this.menuModel = menuModel;
	}

	public void setOrdenProdID(String ordenProdID) {
		this.ordenProdID = ordenProdID;
	}

	public List<OrdenProduccion> getOrdenesProd() {
		return ordenesProd;
	}

	public void setOrdenesProd(List<OrdenProduccion> ordenesProd) {
		this.ordenesProd = ordenesProd;
	}

	public IProduccionService getProduccionService() {
		return produccionService;
	}

	public void setProduccionService(IProduccionService produccionService) {
		this.produccionService = produccionService;
	}

	public OrdenProduccion getSelectedOp() {
		return selectedOp;
	}

	public void setSelectedOp(OrdenProduccion selectedOp) {
		this.selectedOp = selectedOp;
	}

	public boolean isRenderOpDetails() {
		return renderOpDetails;
	}

	public void setRenderOpDetails(boolean renderOpDetails) {
		this.renderOpDetails = renderOpDetails;
	}

	public UserBean getUserBean() {
		return userBean;
	}

	public void setUserBean(UserBean userBean) {
		this.userBean = userBean;
	}

	public TipoMaterial getTipoMaterial() {
		return tipoMaterial;
	}

	public void setTipoMaterial(TipoMaterial tipoMaterial) {
		this.tipoMaterial = tipoMaterial;
	}

	public ProdAction[] getActions() {
		return actions;
	}

	public void setActions(ProdAction[] actions) {
		this.actions = actions;
	}

	public ProdAction getAction() {
		return action;
	}

	public void setAction(ProdAction action) {
		this.action = action;
	}

	public boolean isShowComment() {
		return showComment;
	}

	public void setShowComment(boolean showComment) {
		this.showComment = showComment;
	}

	public String getComment() {
		return comment;
	}

	public void setComment(String comment) {
		this.comment = comment;
	}

	public UserHomeMenuBean getHomeBean() {
		return homeBean;
	}

	public void setHomeBean(UserHomeMenuBean homeBean) {
		this.homeBean = homeBean;
	}

	public EstadoProduccion getEstadoFiltro() {
		return estadoFiltro;
	}

	public void setEstadoFiltro(EstadoProduccion estadoFiltro) {
		this.estadoFiltro = estadoFiltro;
	}

	public boolean isRenderOpComments() {
		return renderOpComments;
	}

	public void setRenderOpComments(boolean renderOpComments) {
		this.renderOpComments = renderOpComments;
	}

	public boolean isRenderPerformedWork() {
		return renderPerformedWork;
	}

	public void setRenderPerformedWork(boolean renderPerformedWork) {
		this.renderPerformedWork = renderPerformedWork;
	}

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}

	public List<ExtPerformedWork> getExtPerformedWorks() {
		return extPerformedWorks;
	}

	public void setExtPerformedWorks(List<ExtPerformedWork> extPerformedWorks) {
		this.extPerformedWorks = extPerformedWorks;
	}

	public Long getSelectedId() {
		return selectedId;
	}

	public void setSelectedId(Long selectedId) {
		this.selectedId = selectedId;
	}

	public Long getTemporalId() {
		return temporalId;
	}

	public void setTemporalId(Long temporalId) {
		this.temporalId = temporalId;
	}

	public FormulasBean getFormulaBean() {
		return formulaBean;
	}

	public void setFormulaBean(FormulasBean formulaBean) {
		this.formulaBean = formulaBean;
	}

	public List<ExtProdScrap> getExtScrap() {
		return extScrap;
	}

	public void setExtScrap(List<ExtProdScrap> extScrap) {
		this.extScrap = extScrap;
	}

	public List<ImpPerformedWork> getImpPerformedWorks() {
		return impPerformedWorks;
	}

	public void setImpPerformedWorks(List<ImpPerformedWork> impPerformedWorks) {
		this.impPerformedWorks = impPerformedWorks;
	}

	public List<ImpProdScrap> getImpScrap() {
		return impScrap;
	}

	public void setImpScrap(List<ImpProdScrap> impScrap) {
		this.impScrap = impScrap;
	}

	public List<ConfPerformedWork> getConfPerformedWorks() {
		return confPerformedWorks;
	}

	public void setConfPerformedWorks(List<ConfPerformedWork> confPerformedWorks) {
		this.confPerformedWorks = confPerformedWorks;
	}

	public List<ConfProdScrap> getConfScrap() {
		return confScrap;
	}

	public void setConfScrap(List<ConfProdScrap> confScrap) {
		this.confScrap = confScrap;
	}

	public Long getImpTemporalId() {
		return impTemporalId;
	}

	public void setImpTemporalId(Long impTemporalId) {
		this.impTemporalId = impTemporalId;
	}

	public Long getScrapTemporalId() {
		return scrapTemporalId;
	}

	public void setScrapTemporalId(Long scrapTemporalId) {
		this.scrapTemporalId = scrapTemporalId;
	}

	public List<ProdOperator> getOperatorsAutocomp() {
		return operatorsAutocomp;
	}

	public void setOperatorsAutocomp(List<ProdOperator> operatorsAutocomp) {
		this.operatorsAutocomp = operatorsAutocomp;
	}

	public ProdOperator getSelectedOperator() {
		return selectedOperator;
	}

	public void setSelectedOperator(ProdOperator selectedOperator) {
		this.selectedOperator = selectedOperator;
	}

	public String getSelectedOperatorStr() {
		return selectedOperatorStr;
	}

	public void setSelectedOperatorStr(String selectedOperatorStr) {
		this.selectedOperatorStr = selectedOperatorStr;
	}

	public ExtPerformedWork getExtEditingRow() {
		return extEditingRow;
	}

	public void setExtEditingRow(ExtPerformedWork extEditingRow) {
		this.extEditingRow = extEditingRow;
	}

	public Date getCurrentDate() {
		return currentDate;
	}

	public void setCurrentDate(Date currentDate) {
		this.currentDate = currentDate;
	}

}
